package redis

import (
	"context"
	"time"
)

// 设置指定 key 的值，设置指定秒单位时间过期，0 则为永不过期，成功返回 "OK"
func (h *Handler) Set(key string, value string, second int64) (status string, err error) {
	status, err = h.Client.Set(context.Background(), key, value, time.Duration(second)*time.Second).Result()
	go h.Log("String-Set", []interface{}{key, value, second}, status, err)
	return
}

// 只有在 key 不存在时设置 key 的值，设置指定秒单位时间过期，0 则为永不过期
func (h *Handler) SetNX(key string, value string, second int64) (status bool, err error) {
	status, err = h.Client.SetNX(context.Background(), key, value, time.Duration(second)*time.Second).Result()
	go h.Log("String-SetNX", []interface{}{key, value, second}, status, err)
	return
}

// 获取指定 key 的值
func (h *Handler) Get(key string) (value string, err error) {
	value, err = h.Client.Get(context.Background(), key).Result()
	go h.Log("String-Get", key, value, err)
	return
}

// 获取并删除指定 key 的值
func (h *Handler) GetWithDel(key string) (value string, err error) {
	defer h.Log("String-GetWithDel", key, value, err)
	// 获取值
	ctx := context.Background()
	value, err = h.Client.Get(ctx, key).Result()
	if err != nil {
		return value, err
	}
	// 删除键值
	_, err = h.Client.Del(ctx, key).Result()
	return
}

// 返回 key 中字符串值的子字符
func (h *Handler) GetRange(key string, start int64, end int64) (child string, err error) {
	child, err = h.Client.GetRange(context.Background(), key, start, end).Result()
	go h.Log("String-GetRange", []interface{}{key, start, end}, child, err)
	return
}

// 将给定 key 的值设为 value ，并返回 key 的旧值(old value)
func (h *Handler) GetSet(key string, value string) (old string, err error) {
	old, err = h.Client.GetSet(context.Background(), key, value).Result()
	go h.Log("String-GetSet", []interface{}{key, value}, old, err)
	return
}

// 对 key 所储存的字符串值，设置或清除指定偏移量上的位(bit)
func (h *Handler) SetBit(key string, offset int64, value int) (count int64, err error) {
	count, err = h.Client.SetBit(context.Background(), key, offset, value).Result()
	go h.Log("String-SetBit", []interface{}{key, offset, value}, count, err)
	return
}

// 对 key 所储存的字符串值，获取指定偏移量上的位(bit)
func (h *Handler) GetBit(key string, offset int64) (bit int64, err error) {
	bit, err = h.Client.GetBit(context.Background(), key, offset).Result()
	go h.Log("String-GetBit", []interface{}{key, offset}, bit, err)
	return
}

// 获取所有(一个或多个)给定 key 的值
func (h *Handler) MGet(keys ...string) (values []interface{}, err error) {
	values, err = h.Client.MGet(context.Background(), keys...).Result()
	go h.Log("String-MGet", keys, values, err)
	return
}

// 用 value 参数覆写给定 key 所储存的字符串值，从偏移量 offset 开始
func (h *Handler) SetRange(key string, offset int64, value string) (len int64, err error) {
	len, err = h.Client.SetRange(context.Background(), key, offset, value).Result()
	go h.Log("String-SetRange", []interface{}{key, offset, value}, len, err)
	return
}

// 返回 key 所储存的字符串值的长度
func (h *Handler) StrLen(key string) (len int64, err error) {
	len, err = h.Client.StrLen(context.Background(), key).Result()
	go h.Log("String-StrLen", key, len, err)
	return
}

// 同时设置一个或多个 key-value 对
func (h *Handler) MSet(keyValues ...interface{}) (status string, err error) {
	status, err = h.Client.MSet(context.Background(), keyValues).Result()
	go h.Log("String-MSet", keyValues, status, err)
	return
}

// 同时设置一个或多个 key-value 对，当且仅当所有给定 key 都不存在
func (h *Handler) MSetNX(keyValues ...interface{}) (status bool, err error) {
	status, err = h.Client.MSetNX(context.Background(), keyValues).Result()
	go h.Log("String-MSetNX", keyValues, status, err)
	return
}

// 将 key 中储存的数字值增一，返回处理结果值
func (h *Handler) Incr(key string) (value int64, err error) {
	value, err = h.Client.Incr(context.Background(), key).Result()
	go h.Log("String-Incr", key, value, err)
	return
}

// 将 key 所储存的值加上给定的增量值，返回处理结果值
func (h *Handler) IncrBy(key string, incr int64) (value int64, err error) {
	value, err = h.Client.IncrBy(context.Background(), key, incr).Result()
	go h.Log("String-IncrBy", []interface{}{key, incr}, value, err)
	return
}

// 将 key 所储存的值加上给定的浮点增量值，返回处理结果值
func (h *Handler) IncrByFloat(key string, incr float64) (value float64, err error) {
	value, err = h.Client.IncrByFloat(context.Background(), key, incr).Result()
	go h.Log("String-IncrByFloat", []interface{}{key, incr}, value, err)
	return
}

// 将 key 中储存的数字值减一，返回处理结果值
func (h *Handler) Decr(key string) (value int64, err error) {
	value, err = h.Client.Decr(context.Background(), key).Result()
	go h.Log("String-Decr", key, value, err)
	return
}

// key 所储存的值减去给定的减量值，返回处理结果值
func (h *Handler) DecrBy(key string, decr int64) (value int64, err error) {
	value, err = h.Client.DecrBy(context.Background(), key, decr).Result()
	go h.Log("String-DecrBy", []interface{}{key, decr}, value, err)
	return
}

// 如果 key 不存在，则添加键值；如果已经存在并且是一个字符串， APPEND 命令将指定的 value 追加到该 key 原来值（value）的末，返回结果字符串长度
func (h *Handler) Append(key string, value string) (len int64, err error) {
	len, err = h.Client.Append(context.Background(), key, value).Result()
	go h.Log("String-Append", []interface{}{key, value}, len, err)
	return
}
